/// This module provides two string hash functions:
/// - `string_hash`: A case-sensitive hash function using the djb2 algorithm.
/// - `string_nocase_hash`: A case-insensitive hash function using the djb2 algorithm.

pub mod hash_functions {
    /// Computes a case-sensitive hash for a given string using the djb2 algorithm.
    ///
    /// # Arguments
    ///
    /// * `string` - A reference to a string slice (`&str`) to be hashed.
    ///
    /// # Returns
    ///
    /// An unsigned 32-bit integer representing the hash value.
    pub fn string_hash(string: &str) -> u32 {
        let mut result: u32 = 5381;

        for &c in string.as_bytes() {
            result = (result << 5).wrapping_add(result).wrapping_add(c as u32);
        }

        result
    }

    /// Computes a case-insensitive hash for a given string using the djb2 algorithm.
    ///
    /// # Arguments
    ///
    /// * `string` - A reference to a string slice (`&str`) to be hashed.
    ///
    /// # Returns
    ///
    /// An unsigned 32-bit integer representing the hash value.
    pub fn string_nocase_hash(string: &str) -> u32 {
        let mut result: u32 = 5381;

        for &c in string.as_bytes() {
            let lower_char = c.to_ascii_lowercase();
            result = (result << 5).wrapping_add(result).wrapping_add(lower_char as u32);
        }

        result
    }
}

#[cfg(test)]
mod tests {
    use super::hash_functions::*;

    #[test]
    fn test_string_hash() {
        let test_string = "Hello, World!";
        let expected_hash: u32 = 1776219522; // Precomputed hash value
        assert_eq!(string_hash(test_string), expected_hash);
    }

    #[test]
    fn test_string_nocase_hash() {
        let test_string = "Hello, World!";
        let expected_hash: u32 = 1776219522; // Precomputed hash value (same as case-sensitive for this input)
        assert_eq!(string_nocase_hash(test_string), expected_hash);
    }

    #[test]
    fn test_case_insensitive_hash() {
        let test_string_upper = "HELLO";
        let test_string_lower = "hello";
        assert_eq!(string_nocase_hash(test_string_upper), string_nocase_hash(test_string_lower));
    }
}
